package com.zoowii.jpa_utils.util.cache;
import com.google.common.base.Function;
import com.zoowii.jpa_utils.util.ListUtil;
import org.apache.commons.lang3.tuple.Pair;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by zoowii on 16/2/20.
*/
public class MemoryCache<K, V> implements ICache<K, V> {
private int maxEntriesCount = 10000;
public int getMaxEntriesCount() {
return maxEntriesCount;
}
public void setMaxEntriesCount(int maxEntriesCount) {
this.maxEntriesCount = maxEntriesCount;
}
public boolean isCacheFull() {
synchronized (cache) {
return cache.size() >= maxEntriesCount;
}
}
private final Map<K, Pair<V, Long>> cache = new ConcurrentHashMap<K, Pair<V, Long>>();
@Override
public void put(K key, V value) {
if (isCacheFull()) {
clean();
}
cache.put(key, Pair.of(value, -1L));
}
@Override
public void put(K key, V value, int timeoutSeconds) {
if (isCacheFull()) {
clean();
}
Date now = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
calendar.add(Calendar.SECOND, timeoutSeconds);
cache.put(key, Pair.of(value, calendar.getTime().getTime()));
}
@Override
public V get(K key) {
Pair<V, Long> pair = cache.get(key);
if(pair == null) {
return null;
}
if(pair.getRight()<0) {
return pair.getLeft();
}
Date date = new Date(pair.getRight());
if(date.before(new Date())) {
return null;
} else {
return pair.getLeft();
}
}
@Override
public void remove(K key) {
cache.remove(key);
}
@Override
public void clean() {
cache.clear();
}
@Override
public int size() {
return cache.size();
}
@Override
public Set<K> keys() {
return cache.keySet();
}
@Override
public Collection<V> values() {
List<Pair<V, Long>> pairs = new ArrayList<Pair<V, Long>>();
pairs.addAll(cache.values());
return ListUtil.map(ListUtil.filter(pairs, new Function<Pair<V, Long>, Boolean>() {
@Override
public Boolean apply(Pair<V, Long> pair) {
if (pair == null) {
return false;
}
if (pair.getRight() < 0) {
return true;
}
Date date = new Date(pair.getRight());
if (date.before(new Date())) {
return false;
} else {
return true;
}
}
}), new Function<Pair<V, Long>, V>() {
@Override
public V apply(Pair<V, Long> pair) {
return pair.getLeft();
}
});
}
}